package com.gjintel.framework.util;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import org.codehaus.jackson.map.ObjectMapper;
import org.dom4j.*;
import com.alibaba.fastjson.JSONObject;


import com.gjintel.framework.util.dto.JXml;

public class XmlParserUtil {

	public static void main(String[] args) throws Exception {
		String str1="<?xml version='1.0' encoding='UTF-8'?>  "
				+"<root>                                  "           
				+"<body>				                  "        
				+"<TransCode>******</TransCode>		      "            
				+"<TransRltMsg > ******</TransRltMsg >		"		   
				+"<SeqNo>******</SeqNo>                   "
				+"<TransDate >******</TransDate >         "
				+"<TransTime >******</TransTime >		  "           
				+"<IAcctNo >******</IAcctNo >		      "         
				+"<AuthCode >******</AuthCode >		      "                 
				+"</body>                                 "
				+"</root>                                 ";
		
		String str2=
				"<?xml version='1.0' encoding='UTF-8'?>  "
						+"<root>                                  "
						+"<head>                                  "
						+"<TransCode>******</TransCode>		      "
						+"<TransDate>*******</TransDate>			"
						+"<TransTime>******</TransTime>		      "
						+"<SeqNo>******</SeqNo>                   "
						+"</head>                                 "
						+"<body>				                  "
						+"<Result>******</Result>		          "
						+"<AddWord>******</AddWord>		          "
						+"<bank>                                  "
						+"<InDate>******</InDate>		          "    
						+"<InTime>******</InTime>		          "            
						+"<InAmount>******</InAmount>		      "           
						+"<InName>******</InName>		          "                 
						+"<InAcct>******</InAcct>		          "                     
						+"<InMemo>******</InMemo>		          "                      
						+"<HstSeqNum>******</HstSeqNum>		      "                          
						+"<PunInst>******</PunInst>		          "                            
						+"<Gernal>******</Gernal>		          "
						+"</bank>                                 "
						+"<bank>                                  "
						+"<InDate>******</InDate>		          "    
						+"<InTime>******</InTime>		          "            
						+"<InAmount>******</InAmount>		      "           
						+"<InName>******</InName>		          "                 
						+"<InAcct>******</InAcct>		          "                     
						+"<InMemo>******</InMemo>		          "                      
						+"<HstSeqNum>******</HstSeqNum>		      "                          
						+"<PunInst>******</PunInst>		          "                            
						+"<Gernal>******</Gernal>		          "
						+"</bank>                                 "
						+"</body>                                 "
						+"</root>                                 ";
		
		String str3="<?xml version='1.0' encoding='UTF-8'?>  "
				+"<root>                                  "
				+"<head>                                  "
				+"<TransCode>******</TransCode>		      "
				+"<TransDate>*******</TransDate>			"
				+"<TransTime>******</TransTime>		      "
				+"<SeqNo>******</SeqNo>                   "
				+"</head>                                 "            
				+"<body>				                  "
				+"<Result>******</Result>		          "  
				+"<AddWord>******</AddWord>		          "                 
				+"<IsPay>******</IsPay>		              "                 
				+"<InTime>******</InTime>		          "                      
				+"<InAmount>******</InAmount>		      "                      
				+"<InName>******</InName>		          "                      
				+"<InAcct>******</InAcct>		          "                            
				+"<InMemo>******</InMemo>		          "                            
				+"<HstSeqNum>******</HstSeqNum>		      "                                  
				+"<PunInst>******</PunInst>		          "                                     
				+"<Gernal>******</Gernal>		          "
				+"</body>                                 "
				+"</root>                                 ";
		
		String str4="<?xml version='1.0' encoding='UTF-8'?>  "
				+"<root>                                  "
				+"<head>                                  "
				+"<TransCode>******</TransCode>           "
				+"<TransDate>*******</TransDate>          "
				+"<TransTime>******</TransTime>           "
				+"<SeqNo>******</SeqNo>                   "
				+"</head>                                 "
				+"<body>                                  "
				+"<AddWord>******</AddWord>               "
				+"<bank>                                  "
				+"<HstSeqNum>******</HstSeqNum>           "
				+"<InAcctNo>******</InAcctNo>             "
				+"<InName>******</InName>                 "
				+"<Result>******</Result>                 "
				+"</bank>                                 "
				+"<bank>                                  "
				+"<HstSeqNum>******</HstSeqNum>           "
				+"<InAcctNo>******</InAcctNo>             "
				+"<InName>******</InName>                 "
				+"<Result>******</Result>                 "
				+"</bank>                                 "
				+"</body>                                 "
				+"</root>                                 ";
		
		String str5="<?xml version='1.0' encoding='UTF-8'?>  "
				+"<root>                                  "           
				+"<body>                                  "
				+"<TransCode>******</TransCode>		      "             
				+"<Result>******</Result>		          "
				+"<AddWord>******</AddWord>               "
				+"</body>                                 "
				+"</root>                                 ";
		
		String str6="<?xml version='1.0' encoding='UTF-8'?>  "
				+"<root>                                  "
				+"<head>                                  "
				+"<TransCode>******</TransCode>		      "
				+"<TransDate>*******</TransDate>			"
				+"<TransTime>******</TransTime>		      "
				+"<SeqNo>******</SeqNo>                   "
				+"</head>                                 "
				+"<body>				                  "
				+"<Result>******</Result>		          "
				+"<AddWord>******</AddWord>		          "
				+"<bank>                                  "
				+"<InDate>******</InDate>		          "    
				+"<InTime>******</InTime>		          "            
				+"<InAmount>******</InAmount>		      "           
				+"<InName>******</InName>		          "                 
				+"<InAcct>******</InAcct>		          "                     
				+"<InMemo>******</InMemo>		          "                      
				+"<HstSeqNum>******</HstSeqNum>		      "
				+"<PunInst>******</PunInst>               "
				+"<BjPunInst>******</BjPunInst>           "       
				+"<Result>******</Result>		          "                            
				+"<AddWord>******</AddWord>		          "
				+"</bank>                                 "
				+"<bank>                                  "
				+"<InDate>******</InDate>		          "    
				+"<InTime>******</InTime>		          "            
				+"<InAmount>******</InAmount>		      "           
				+"<InName>******</InName>		          "                 
				+"<InAcct>******</InAcct>		          "                     
				+"<InMemo>******</InMemo>		          "                      
				+"<HstSeqNum>******</HstSeqNum>		      "
				+"<PunInst>******</PunInst>               "
				+"<BjPunInst>******</BjPunInst>           "                      
				+"<Result>******</Result>		          "                            
				+"<AddWord>******</AddWord>		          "
				+"</bank>                                 "
				+"</body>                                 "
				+"</root>                                 ";
		
		
		// JXml jxml1=xmlParserJavaBean(str1);
		//System.out.println(str2);
		//JXml jxml2=xmlParserJavaBean(str2);
		// JXml jxml3=xmlParserJavaBean(str3);
		// JXml jxm4=xmlParserJavaBean(str4);
		// JXml jxm5=xmlParserJavaBean(str5);
//		JXml jxm6 = xmlParserJavaBean(str6);
		
		String path="";
		//1
//		path=CommUtil.readStringFromFile(XmlParserUtil.class.getResource("/").getPath()+"/"+"test1.xml");
		
		//2
//		path=CommUtil.readStringFromFile(XmlParserUtil.class.getResource("/").getPath()+"/"+"test2.xml");
		
		//3
		path=CommUtil.readStringFromFile(XmlParserUtil.class.getResource("/").getPath()+"/"+"test3.xml");
		
		//4
//		path=CommUtil.readStringFromFile(XmlParserUtil.class.getResource("/").getPath()+"/"+"test4.xml");
		
		
//		path=CommUtil.readStringFromFile(XmlParserUtil.class.getResource("/").getPath()+"/"+"test5.xml");
		
		String xml = CommUtil.freemarkerProcess(null,path);
		//System.err.println(xml);
		JXml jxml=xmlParserJavaBean(xml);
		
		System.err.println(jxml);
	}
	
	/**
	 * 将XML转化为Java对象
	 * @param xml
	 * @return
	 */
	public static JXml xmlParserJavaBean(String xml){
		xml=xml.replaceAll("<BanK>","<bank>");
		xml=xml.replaceAll("</BanK>","</bank>");
		
		//处理bank只有一条的数据
		int bankCount = getCount(xml, "</bank>");
		if(bankCount==1){
			xml=xml.replace("</bank>", "</bank><bank><InDate></InDate></bank>");
		}
		
		//将XML转化为json对象
        String json = null;
        JSONObject jsonObj=new JSONObject();
//        try {
//            jsonObj = XML.toJSONObject(xml);//xml对象
//        } catch (JSONException e) {
//            e.printStackTrace();
//        }
		Document doc= null;
		try {
			doc = DocumentHelper.parseText(xml);
		} catch (DocumentException e) {
			e.printStackTrace();
		}

		dom4j2Json(doc.getRootElement(),jsonObj);

        System.err.println(jsonObj.toString());
        
        //将json对象转化成Java对象
        ObjectMapper om = new ObjectMapper();
        JXml jxml=null;
		try {
			jxml = om.readValue(jsonObj.toString(), JXml.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
        return jxml;
	}
	
	
	/**
	 * 计算字符串出现的次数
	 * @param str
	 * @param sub
	 * @return
	 */
	public static int getCount(String str, String sub) {
		int index = 0;
		int count = 0;
		while ((index = str.indexOf(sub, index)) != -1) {

			index = index + sub.length();
			count++;
		}
		return count;
	}

	 public static String readFile(String path) throws Exception {
        File file=new File(path);
        FileInputStream fis = new FileInputStream(file);
        FileChannel fc = fis.getChannel();
        ByteBuffer bb = ByteBuffer.allocate(new Long(file.length()).intValue());
        //fc向buffer中读入数据
        fc.read(bb);
        bb.flip();
        String str=new String(bb.array(),"UTF8");
        fc.close();
        fis.close();
        return str;

    }
    /**
     * xml转json
     * @param xmlStr
     * @return
     * @throws DocumentException
     */
    public static com.alibaba.fastjson.JSONObject xml2Json(String xmlStr) throws DocumentException{
        Document doc= DocumentHelper.parseText(xmlStr);
        com.alibaba.fastjson.JSONObject json=new com.alibaba.fastjson.JSONObject();
        dom4j2Json(doc.getRootElement(), json);
        return json;
    }

    /**
     * xml转json
     * @param element
     * @param json
     */
    public static void dom4j2Json(Element element, com.alibaba.fastjson.JSONObject json){
        //如果是属性
        for(Object o:element.attributes()){
            Attribute attr=(Attribute)o;
            if(!isEmpty(attr.getValue())){
                json.put("@"+attr.getName(), attr.getValue());
            }
        }
        List<Element> chdEl=element.elements();//获取所有子节点
        if(chdEl.isEmpty()&&!isEmpty(element.getText())){//如果没有子元素,只有一个值
            json.put(element.getName(), element.getText());
        }

        for(Element e:chdEl){//有子元素
            if(!e.elements().isEmpty()){//子元素也有子元素
                com.alibaba.fastjson.JSONObject chdjson=new com.alibaba.fastjson.JSONObject();
                dom4j2Json(e,chdjson);
                Object o=json.get(e.getName());
                if(o!=null){
                    JSONArray jsona=null;
                    if(o instanceof com.alibaba.fastjson.JSONObject){//如果此元素已存在,则转为jsonArray
                        com.alibaba.fastjson.JSONObject jsono=(com.alibaba.fastjson.JSONObject)o;
                        json.remove(e.getName());
                        jsona=new JSONArray();
                        jsona.add(jsono);
                        jsona.add(chdjson);
                    }
                    if(o instanceof JSONArray){
                        jsona=(JSONArray)o;
                        jsona.add(chdjson);
                    }
                    json.put(e.getName(), jsona);
                }else{
                    if(!chdjson.isEmpty()){
                        json.put(e.getName(), chdjson);
                    }
                }


            }else{//子元素没有子元素
                for(Object o:element.attributes()){
                    Attribute attr=(Attribute)o;
                    if(!isEmpty(attr.getValue())){
                        json.put("@"+attr.getName(), attr.getValue());
                    }
                }
                if(!e.getText().isEmpty()){
                    json.put(e.getName(), e.getText());
                }
            }
        }
    }

    public static boolean isEmpty(String str) {

        if (str == null || str.trim().isEmpty() || "null".equals(str)) {
            return true;
        }
        return false;
    }

}

